// 暂停容器
let suspendMap = new Map()
//
const IP = "localhost"
// 继续接口链接
const continueURL = `http://${IP}:8084/continueVehicle?vehicleCode=`;

/**
 * 继续工作按钮
 */
function continueWork(e, code) {
    $(e).parentsUntil($("#continueMsg")).fadeOut();
    getAjax(continueURL + code);
    suspendMap[code] = 0;
}

/**
 * 添加提示信息
 */
function appendMsg(code, info, type) {
    let template = '';
    switch (type) {
        case 'before':
            template = `<li>
                        <span>${code} ${info}是否可以继续?</span>
                        <span onclick='continueWork(this,\"${code}\")'>继续</span>
                    </li>`;
            break;
        case 'after':
            template = `<li>
                        <span>${code} ${info}是否可以继续?</span>
                        <span onclick='continueWork(this,\"${code}\")'>继续</span>
                    </li>`;
            break;
        case 'timing':
            template = `<li class="${code}">
                        <span>${code} 号车定时任务，倒计时 <span>${info}</span> 秒</span>
                    </li>`;
            break;
    }
    $("#continueMsg").append(template);
}

/**
 * 定时任务处理 ,先判断定时任务再判断后置任务
 */
function verifyTimingHandler(dataSource) {
    let data = dataSource;
    console.log(data)
    let code = data.deviceNo;
    // 后置处理
    if (data.pauseTime > 0) {
        console.log('有停留');
        if (suspendMap[code] !== 1) {
            suspendMap[code] = 1;
            let count = data.pauseTime;
            appendMsg(code, count, 'timing');
            let interval = setInterval(function () {
                count--;
                $("." + code + " > span > span").html(count);
            }, 1000);
            setTimeout(function () {
                $("." + code).fadeOut();
                suspendMap[code] = 0;
                getAjax(continueURL + code);
                clearInterval(interval);
                verifyBeforeSuspendHandler(data);
            }, count * 1000);
        }
    } else {
        verifyBeforeSuspendHandler(data);
    }
}

/**
 * 前置接口调用,实现暂停等待接口响应
 */
function verifyBeforeSuspendHandler(status) {
    let code = status.deviceNo;
    let outAppInterfaceNo = status.outAppInterfaceNo;
    if (outAppInterfaceNo !== undefined && outAppInterfaceNo !== '') {
        console.log('有前置');
        if (suspendMap[code] !== 1) {
            verifyTimingHandler(data.status)
            suspendMap[code] = 1;
            appendMsg(code, '该车辆前置', 'before');
        }
    } else {
        setPushMessage(status);
        verifyAfterSuspendHandler(status);
    }
}

function verifyAfterSuspendHandler(status) {
    let code = status.deviceNo;
    let callbackInterfaceNo = status.callbackInterfaceNo;
    if (callbackInterfaceNo !== undefined && callbackInterfaceNo !== '') {
        console.log('有后置');
        if (suspendMap[code] !== 1) {
            suspendMap[code] = 1;
            appendMsg(code, '该车辆后置', 'after');
        }
    }
}

function getAjax(url) {
    let result = "";
    $.ajax({
        url: url,
        cache: false,
        async: false,
        success: function (data) {
            result = data;
        }
    });
    return result;
}


/*device 对象*/
//数据极值 ( x 轴最大/最小 ,y轴 最大/最小)
let mapDataExtremumVO = {
    xMax: '',
    xMin: '',
    yMax: '',
    yMin: ''
};
//地图比例尺,取最小比例
let scale;
//点位map
let pointsMap = new Map();
//点位map
let linesMap = new Map();
//点位map
let agvDeviceMap = new Map();
//点位 list
let pointList;
//线 对象 list
let lineList;
/* gav 小车图片 */
let binImage;
//画布
let canvas = null;
let ctx = null;


/**
 * 初始化布局
 * */
const canvasWidth = 1400; //canvas宽度
const canvasHeight = 800; //canvas高度

var context; //画布
var cacheCanvas;//缓存容器
//点位前缀
let pointPrefix = "";
//点位编号显示位数(从最后一位往前)
let pointFix = 3;
//比例尺常量(点位与边缘距离(两边相加之和))
let scaleConstant = 100;

/**
 * 启动时自动加载
 */
$(function () {
    getAjax(`http://${IP}:8084/continueAll`)
    console.log("启动自动加载程序");
    canvas = document.getElementById("myCanvas");
    context = canvas.getContext("2d");

    canvas.width = canvasWidth;
    canvas.height = canvasHeight;
    context.save();

    cacheCanvas = document.createElement("canvas");
    cacheCanvas.width = canvasWidth;
    cacheCanvas.height = canvasHeight;
    ctx = cacheCanvas.getContext("2d");
    //设置原点在底部
    ctx.save();
    ctx.translate(0, canvasHeight);
    binImage = new Image();
    binImage.src = 'images/agv.png';

    //初始化地图数据
    initMapData();
    //图片加载完成之后再绘制,否则会加载不出图片的
    binImage.onload = function () {
        //初始化画布
        initCanvas();
    }
});

let mapDataObj = {
    mapDataPointList: '',
    mapDataExtremum: '',
    mapDataLineList: ''
};

/**
 * 初始化所有地图数据
 */
function initMapData() {
    let mapData = ajaxFunction("getMapData");
    mapDataObj = JSON.parse(mapData);
    pointList = mapDataObj.mapDataPointList;
    lineList = mapDataObj.mapDataLineList;
    mapDataExtremumVO = mapDataObj.mapDataExtremum;
    //x 比例尺
    let xScale = (canvasWidth - scaleConstant * 2) / (mapDataExtremumVO.xMax - mapDataExtremumVO.xMin);
    //y 比例尺
    let yScale = (canvasHeight - scaleConstant) / (mapDataExtremumVO.yMax - mapDataExtremumVO.yMin);
    // 地图比例尺(选用最小比例)
    scale = xScale < yScale ? xScale : yScale;
    setPointsMap();
}

/**
 * 用map 保存所有点位(key:点位号 value:点位对象)
 */
function setPointsMap() {
    for (let i = 0; i < pointList.length; i++) {
        //换算成页面能用的坐标
        pointList[i].xCoordinate = xCoordinateMapping(pointList[i].xCoordinate);
        pointList[i].yCoordinate = yCoordinateMapping(pointList[i].yCoordinate);
        pointsMap.set(pointList[i].nodeCode, pointList[i]);
        linesMap.set(pointList[i].mainKey, pointList[i]);
    }
}

/**
 * 推送数据
 */
function setPushMessage(pushDeviceStatus) {
    pushDeviceStatus.x = xCoordinateMapping(pushDeviceStatus.xCoordinate);
    pushDeviceStatus.y = yCoordinateMapping(pushDeviceStatus.yCoordinate);
    agvDeviceMap.set(pushDeviceStatus.deviceNo, pushDeviceStatus);
    initCanvas();
}

/**
 * 刷新画布
 */
function initCanvas() {
    //清空画布
    context.clearRect(0, 0, canvasWidth, canvasHeight);
    //重新构建基础元素
    refreshBaseElement();
    agvDeviceMap.forEach(function (agv, key) {
        //画小车
        initCar(key);
    });
    context.clearRect(0, 0, canvasWidth, canvasHeight);
    context.drawImage(this.cacheCanvas, 0, 0, canvasWidth, canvasHeight);
}

/**
 * 刷新基础元素
 */
function refreshBaseElement() {
    ctx.save();
    ctx.clearRect(0, 0, canvasWidth, -canvasHeight);
    ctx.restore();
    initPoints();
    initLines();
}

/**
 * 画点
 */
function initPoints() {
    ctx.save();
    for (let i = 0; i < pointList.length; i++) {
        ctx.beginPath();
        ctx.strokeStyle = "rgb(153,153,153)";
        //充电点
        if ("charge" === pointList[i].nodeType) {
            ctx.strokeStyle = "rgb(255,24,41)";
        }
        //待命点
        if ("standby" === pointList[i].nodeType) {
            ctx.strokeStyle = "rgb(50,33,255)";
        }
        //仓储点
        if ("storage" === pointList[i].nodeType) {
            ctx.strokeStyle = "rgb(65,255,11)";
        }
        //工作区
        if ("working" === pointList[i].nodeType) {
            ctx.strokeStyle = "rgb(255,53,238)";
        }
        ctx.rect(pointList[i].xCoordinate - 5, pointList[i].yCoordinate - 5, 10, 10);
        ctx.fillText(pointList[i].nodeCode.substring(pointList[i].nodeCode.length - pointFix, pointList[i].nodeCode.length), pointList[i].xCoordinate - 10, pointList[i].yCoordinate - 10);
        ctx.stroke();
    }
    ctx.restore();
}

/**
 * 画线
 */
function initLines() {
    ctx.save();
    for (var i = 0; i < lineList.length; i++) {
        ctx.beginPath();
        ctx.lineWidth = 2;
        ctx.lineCap = "butt";
        if (!linesMap.get(lineList[i].fromPoint) || !linesMap.get(lineList[i].toPoint)) {
            continue;
        }
        ctx.moveTo(linesMap.get(lineList[i].fromPoint).xCoordinate, linesMap.get(lineList[i].fromPoint).yCoordinate);
        ctx.lineTo(linesMap.get(lineList[i].toPoint).xCoordinate, linesMap.get(lineList[i].toPoint).yCoordinate);
        ctx.stroke();
    }
    ctx.restore();
}

function initCar(deviceNo) {
    ctx.save();
    ctx.beginPath();

    let x = agvDeviceMap.get(deviceNo).x;
    let y = agvDeviceMap.get(deviceNo).y;
    let liftStatus = agvDeviceMap.get(deviceNo).liftStatus;
    //显示agv小车图片
    if (liftStatus === 1) {
        initBackground(x - 20, y - 65);
    }
    //电量
    initPower(agvDeviceMap.get(deviceNo).power, x - 9, y + 12);
    //举升状态
    initLiftStatus(liftStatus, x - 12, y - 25);
    let angle = agvDeviceMap.get(deviceNo).angle;
    //agv 货架方向
    shelfDirectionHandler(liftStatus, agvDeviceMap.get(deviceNo).shelfDirection, x - 17, y - 42);

    if (angle !== 0) {
        ctx.translate(x, y);
        ctx.rotate(angle * Math.PI / -180);
        ctx.translate(-x, -y);
    }
    // 等待加载完成再绘制
    ctx.drawImage(binImage, x - binImage.width / 2, y - binImage.height / 2);
    ctx.stroke();

    if (angle !== 0) {
        ctx.translate(x, y);
        ctx.rotate(angle * Math.PI / 180);
        ctx.translate(-x, -y);
    }
    //设备编号
    initDeviceNo(deviceNo.substring(deviceNo.length - 1, deviceNo.length), x - 4, y + 4);
    //恢复画布角度
    ctx.restore();
}

/**
 * 画设备编号
 */
function initDeviceNo(message, x, y) {
    ctx.save();
    ctx.beginPath();
    ctx.font = "bold 12px Microsoft YaHei";
    ctx.fillStyle = "rgb(255,255,255)";
    ctx.fillText(message, x, y);
    ctx.restore();
}

/**
 * 货架方向处理
 */
function shelfDirectionHandler(liftStatus, shelfDirection, x, y) {
    if (liftStatus === 1) {
        ctx.save();
        ctx.beginPath();
        //显示文字
        ctx.font = "bold 12px Microsoft YaHei";
        ctx.fillStyle = "rgba(33,0,20,0.97)";
        let text;
        if (shelfDirection === 200) {
            text = '▄▄';
        } else if (shelfDirection === 300) {
            text = ' ▋';
        } else {
            text = '〇';
        }
        ctx.fillText(`货[${text}]`, x, y);
        ctx.restore();
    }
}

/**
 * 画举升状态(仅举升时候显示)
 */
function initLiftStatus(liftStatus, x, y) {
    if (liftStatus === 1) {
        ctx.save();
        ctx.beginPath();
        ctx.fillStyle = "rgba(255,255,255,0.97)";
        ctx.rect(x - 4, y - 11, 30, 14);
        ctx.fill();//填充
        ctx.strokeStyle = "rgba(255,255,255,0.97)";
        ctx.stroke();//绘制边框
        ctx.restore();
        ctx.save();
        ctx.beginPath();
        //显示文字
        ctx.font = "bold 12px Microsoft YaHei";
        ctx.fillStyle = "rgba(255,63,5,0.97)";
        let text = "抬起";
        ctx.fillText(text, x, y);
        ctx.restore();
    }
}

/**
 * 画电量
 */
function initPower(message, x, y) {
    ctx.save();
    ctx.beginPath();
    ctx.fillStyle = message > 20 ? "rgba(65,255,11,0.97)" : "rgba(255,116,148,0.97)";
    ctx.strokeStyle = "rgba(3,3,4,0.99)";
    ctx.fillRect(x, y, 19.5, 9.5);
    ctx.clearRect(x + 0.195 * (message), y - 0.5, 20 - 0.195 * (message), 10.5);

    // 画框
    ctx.beginPath();
    ctx.lineWidth = "1";
    ctx.strokeStyle = "rgba(3,3,4,0.99)";
    ctx.rect(x, y, 20, 10);
    ctx.stroke();

    ctx.beginPath();
    ctx.font = "9px Microsoft YaHei";
    ctx.fillStyle = "rgba(12,4,4,0.97)";
    ctx.fillText(message, x + 2.5, y + 8.5);
    ctx.restore();
}

/**
 * 画背景
 */
function initBackground(x, y) {
    ctx.save();
    ctx.beginPath();
    ctx.fillStyle = "rgba(255,255,255,0.97)";
    ctx.rect(x, y, 40, 50);
    ctx.fill();//填充
    ctx.stroke();//绘制边框
    ctx.restore();
}

/**
 * ajax
 * @param url
 * @returns {string}
 */
function ajaxFunction(url) {
    let result = "";
    $.ajax({
        data: "get",
        url: url,
        cache: false,
        async: false,
        success: function (data) {
            result = data;
        }
    });
    return result;
}

/**
 * x坐标映射
 */
function xCoordinateMapping(xCoordinate) {
    return (xCoordinate - mapDataExtremumVO.xMin) * scale + scaleConstant / 2;
}

/**
 * y坐标映射
 */
function yCoordinateMapping(yCoordinate) {
    return -(yCoordinate - mapDataExtremumVO.yMin) * scale - scaleConstant / 2;
}